﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NBusiness.CodeDom.Compiler;
using NBusiness.CodeDom;
using NBusiness.CodeDom.Services;
using System.Reflection;

namespace NBusiness.ESharp.Testing.Mocks
{
    class MockTypeFinder
    {
        #region ITypeFinderService Members

        public TypeData[] FindAssignableFrom(TypeData baseType)
        {
            Type @base = Type.GetType(baseType.FullName + ", " + baseType.AssemblyName);
            var query = from a in AppDomain.CurrentDomain.GetAssemblies()
                        from t in a.GetTypes()
                        where t != @base && @base.IsAssignableFrom(t)
                        select new TypeData(t);

            return query.ToArray();
        }

        public MethodData[] FindCallableAs(MethodData delegateSignature)
        {
            var query = from a in AppDomain.CurrentDomain.GetAssemblies()
                        from t in a.GetTypes()
                        from m in t.GetMethods(BindingFlags.Static | BindingFlags.Public)                        
                        where 
                            m.ReturnType == delegateSignature.ReturnType &&
                            m.GetParameters().Length == delegateSignature.Signature.Count &&
                            m.GetParameters().All(p => 
                            {
                                var all = m.GetParameters().ToList();
                                int x = all.IndexOf(p);
                                return p.ParameterType == delegateSignature.Signature[p.Name];
                            })
                        select new MethodData(m);

            return query.ToArray();
        }

        #endregion
    }
}
